package com.foohoo.benchmark.jvm;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;

/**
 * 测试即时编译器编译优化(常量折叠)对性能的提升
 * Benchmark                                              Mode  Cnt    Score     Error  Units
 * JustInTimeWithConstantFold.baseline                    avgt    3    3.426 ±   2.171  ns/op
 * JustInTimeWithConstantFold.withConstantFold            avgt    3    4.645 ±   9.648  ns/op
 * JustInTimeWithConstantFold.withConstantFold2           avgt    3    3.581 ±   4.384  ns/op
 * JustInTimeWithConstantFold.withConstantFoldButExclude  avgt    3  111.290 ± 129.692  ns/op
 * JustInTimeWithConstantFold.withoutConstantFold         avgt    3   31.686 ±  15.154  ns/op
 * 一句话结论: 被判定为热点代码后，即时编译器(jit)会通过多种手段对代码进行优化，可以显著提升性能(示例中分别为常量折叠、普通优化和不优化)
 *
 * @author mzdbxqh
 * @date 2020-10-19 19:21
 **/
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 3, time = 1)
@Fork(1)
@Threads(1)
@State(Scope.Benchmark)
public class JustInTimeWithConstantFold {

	private double x = Math.PI;

	private final double constantX = Math.PI;

	@Benchmark
	public void baseline(Blackhole bh) {
		bh.consume(Math.PI);
	}

	@Benchmark
	public void withConstantFold(Blackhole bh) {
		bh.consume(Math.log(Math.PI));
	}

	@Benchmark
	public void withConstantFold2(Blackhole bh) {
		bh.consume(Math.log(constantX));
	}

	@CompilerControl(CompilerControl.Mode.EXCLUDE)
	@Benchmark
	public void withConstantFoldButExclude(Blackhole bh) {
		bh.consume(Math.log(constantX));
	}

	@Benchmark
	public void withoutConstantFold(Blackhole bh) {
		bh.consume(Math.log(x));
	}

}
